#include <iostream>
#include <functional>
#include <C11Muduo/EventLoop.h>
#include <C11Muduo/TcpServer.h>
#include <sstream>
#include <fstream>
#include <string.h>
#include <vector>
#include "cJSON.h"
#include "deal_mysql.h"


using namespace std;

char dbUser[64] = { 0 };
char dbPwd[64] = { 0 };
char db[64] = { 0 };

class Server {
public:
    Server(EventLoop* loop, const InetAddress& addr, const string name) :server(loop, addr, name) {
        serverName = name;
        this->loop = loop;
        server.setConnectionCallback(bind(&Server::onConnectionComing, this, placeholders::_1));
        server.setMessageCallback(bind(&Server::onMessageComing, this, placeholders::_1, placeholders::_2, placeholders::_3));
        server.setThreadNum(2);
    }

    ~Server() {
        mysql_close(mysql_);
    }

    void start() {
        initMysql();
        server.start();
        loop->loop();
    }

private:
    void onConnectionComing(const TcpConnectionPtr& conn) {
        if (conn->connected()) {
            cout << conn->peerAddress().toIpPort() << "->" << conn->localAddress().toIpPort() << endl;
        }
        else {
            cout << "connection is disconncet." << endl;
        }
    }

    void onMessageComing(const TcpConnectionPtr& conn, Buffer* buf, Timestamp tv) {
        string str = buf->retrieveAllAsString();
        cout << "[" << tv.toString() << "]" << "recv data: \n" << str << endl;
        //std::string json_body = "{\"code\":\"200\"}";

        cout << "请求方法：" << getRequestMethod(str) << endl;
        cout << "请求URL：" << getRequestURL(str) << endl;
        cout << "请求JSON：\n" << getRequestJson(str) << endl;


        std::string method = getRequestMethod(str);
        std::string Url = getRequestURL(str);
        std::string json = getRequestJson(str);

        if (method == "POST" || method == "GET") {
            if (Url == "/login") {
                cout << "login" << endl;
                char user[64] = { 0 };
                char pwd[64] = { 0 };
                char token[16] = { 0 };
                if (getUserInfo(json, user, pwd) == 0) {
                    if (checkUserInfo(user, pwd, token) == 0) {
                        cJSON* object = cJSON_CreateObject();
                        cJSON_AddStringToObject(object, "code", "200");
                        cJSON_AddStringToObject(object, "token", token);
                        char* ret = cJSON_Print(object);
                        string strRet(ret);
                        string res = create_http_response(strRet);
                        conn->send(res);
                        conn->shutdown();
                    }
                    else {
                        return_status(conn, "404");
                    }

                }
                else {
                    return_status(conn, "404");
                }

            }
            else if (Url == "/register") {
                cout << "/register" << endl;
                char user[64] = { 0 };
                char pwd[64] = { 0 };

                if (getUserInfo(json, user, pwd) == 0) {
                    char sql_cmd[256] = { 0 };
                    MYSQL* mysql_ = msql_conn(dbUser, dbPwd, db);
                    if (mysql_ == NULL)
                    {
                        cout << "mysql is nullptr" << endl;
                        return;
                    }
                    //设置数据库编码，主要处理中文编码问题
                    mysql_query(mysql_, "set names utf8");

                    char checkUser[128] = { 0 };
                    sprintf(checkUser, "select * from user where userAccount = '%s'", user);
                    char res[64] = { 0 };

                    cout << checkUser << endl;
                    if (mysql_query(mysql_, checkUser) != 0) {
                        return_status(conn, "500");
                        return;
                    }

                    MYSQL_RES* res_set = NULL;
                    res_set = mysql_store_result(mysql_);
                    if (res_set == NULL) {
                        cout << "res_set is NULL" << endl;
                        return_status(conn, "404");
                        return;
                    }

                    unsigned long line = 0;
                    line = mysql_num_rows(res_set);
                    mysql_free_result(res_set);

                    if (line > 0) {
                        return_status(conn, "404");
                        return;
                    }

                    sprintf(sql_cmd, "insert into user (userAccount, userPwd, create_time) value ('%s','%s',now())", user, pwd);
                    cout << sql_cmd << endl;
                    if (mysql_exec(mysql_, sql_cmd) != -1) {
                        return_status(conn, "200");
                    }
                    else {
                        return_status(conn, "500");
                    }
                    mysql_close(mysql_);
                }
                else {
                    return_status(conn, "500");
                }
            }
            else if (Url == "/resetPwd") {
                cout << "resetPwd" << endl;
                char user[64] = { 0 };
                char pwd[64] = { 0 };
                char newPwd[64] = { 0 };
                char token[16] = { 0 };
                if (getUserInfo(json, user, pwd, newPwd) == 0) {
                    if (checkUserInfo(user, pwd, token) == 0) {
                        char sql_cmd[128] = { 0 };
                        MYSQL* mysql_ = msql_conn(dbUser, dbPwd, db);
                        if (mysql_ == NULL)
                        {
                            cout << "mysql is nullptr" << endl;
                            return;
                        }
                        //设置数据库编码，主要处理中文编码问题
                        mysql_query(mysql_, "set names utf8");

                        sprintf(sql_cmd, "update user set userPwd = '%s'where user_id = %s", newPwd, token);
                        cout << sql_cmd << endl;
                        if (mysql_exec(mysql_, sql_cmd) != -1) {
                            return_status(conn, "200");
                        }
                        else {
                            return_status(conn, "500");
                        }

                        mysql_close(mysql_);
                    }
                    else {
                        return_status(conn, "404");
                    }
                }
                else {
                    return_status(conn, "500");
                }
            }
            else if (Url == "/Books") {
                // 返回书城的书籍信息
                char sql_cmd[128] = { 0 };
                MYSQL* mysql_ = msql_conn(dbUser, dbPwd, db);
                if (mysql_ == NULL)
                {
                    cout << "mysql is nullptr" << endl;
                    return;
                }
                //设置数据库编码，主要处理中文编码问题
                mysql_query(mysql_, "set names utf8");

                sprintf(sql_cmd, "select * from books");

                cout << sql_cmd << endl;
                if (mysql_query(mysql_, sql_cmd) != 0) {
                    return_status(conn, "500");
                    return;
                }

                MYSQL_RES* res_set = NULL;
                res_set = mysql_store_result(mysql_);
                if (res_set == NULL) {
                    cout << "res_set is NULL" << endl;
                    return_status(conn, "404");
                    return;
                }

                unsigned long line = 0;
                line = mysql_num_rows(res_set);

                MYSQL_ROW row;

                cJSON* root = cJSON_CreateObject();
                cJSON* array = cJSON_CreateArray();

                while ((row = mysql_fetch_row(res_set)) != NULL) {
                    cJSON* item = cJSON_CreateObject();

                    int column_index = 0;
                    if (row[column_index] != NULL) {
                        cJSON_AddStringToObject(item, "book_id", row[column_index]);
                    }
                    column_index++;

                    if (row[column_index] != NULL) {
                        cJSON_AddStringToObject(item, "book_name", row[column_index]);
                    }

                    column_index++;

                    if (row[column_index] != NULL) {
                        cJSON_AddStringToObject(item, "author", row[column_index]);
                    }

                    column_index++;

                    if (row[column_index] != NULL) {
                        cJSON_AddStringToObject(item, "Url", row[column_index]);
                    }

                    column_index++;

                    if (row[column_index] != NULL) {
                        cJSON_AddStringToObject(item, "content", row[column_index]);
                    }

                    cJSON_AddItemToArray(array, item);
                }
                cJSON_AddStringToObject(root, "code", "200");
                cJSON_AddNumberToObject(root, "count", line);
                cJSON_AddItemToObject(root, "books", array);

                char* ret = cJSON_Print(root);
                string strRet(ret);
                string res = create_http_response(strRet);
                conn->send(res);
                conn->shutdown();

                mysql_free_result(res_set);
                mysql_close(mysql_);
            }
            else if (Url == "/oneBook") {
                //点击一本书时，获取该书籍的文字
                char book_id[16] = { 0 };
                char user_id[16] = { 0 };
                if (getBookID(json, book_id) == 0) {
                    char sql_cmd[128] = { 0 };
                    MYSQL* mysql_ = msql_conn(dbUser, dbPwd, db);
                    if (mysql_ == NULL)
                    {
                        cout << "mysql is nullptr" << endl;
                        return;
                    }
                    //设置数据库编码，主要处理中文编码问题
                    mysql_query(mysql_, "set names utf8");
                    sprintf(sql_cmd, "select content from books where book_id = %s", book_id);

                    char res[64] = { 0 };
                    if (process_result_one(mysql_, sql_cmd, res) == 0) {
                        cJSON* object = cJSON_CreateObject();
                        cJSON_AddStringToObject(object, "code", "200");
                        cJSON_AddStringToObject(object, "content", res);
                        char* ret = cJSON_Print(object);
                        string strRet(ret);
                        string res = create_http_response(strRet);
                        conn->send(res);
                        conn->shutdown();
                    }
                    if (getUserID(json, user_id) == 0) {
                        char sql_cmd[128] = { 0 };
                        sprintf(sql_cmd, "select * from historyBook where book_id = %s AND user_id = %s", book_id, user_id);

                        cout << sql_cmd << endl;
                        if (mysql_query(mysql_, sql_cmd) != 0) {
                            return;
                        }

                        MYSQL_RES* res_set = NULL;
                        res_set = mysql_store_result(mysql_);
                        if (res_set == NULL) {
                            cout << "res_set is NULL" << endl;
                            return;
                        }

                        unsigned long line = 0;
                        line = mysql_num_rows(res_set);

                        char sql_cmd_insert_update[128] = { 0 };
                        if (line == 0) {
                            sprintf(sql_cmd_insert_update, "insert into historyBook values(%s,%s,now())", book_id, user_id);
                        }
                        else {
                            sprintf(sql_cmd_insert_update, "update historyBook set use_time = now() where book_id = %s AND user_id = %s", book_id, user_id);
                        }

                        cout << sql_cmd_insert_update << endl;

                        if (mysql_exec(mysql_, sql_cmd_insert_update) != -1) {
                            cout << "histroy is update" << endl;
                        }
                        mysql_free_result(res_set);
                    }
                    else {
                        return_status(conn, "500");
                        return;
                    }
                    mysql_close(mysql_);
                }
                else {
                    return_status(conn, "404");
                    return;
                }
            }
            else if (Url == "/myBooks") {
                //点击个人书架时，获取信息
                char user_id[16] = { 0 };
                MYSQL* mysql_ = msql_conn(dbUser, dbPwd, db);
                if (mysql_ == NULL)
                {
                    cout << "mysql is nullptr" << endl;
                    return;
                }
                //设置数据库编码，主要处理中文编码问题
                mysql_query(mysql_, "set names utf8");
                if (getUserID(json, user_id) == 0) {
                    char sql_cmd[128] = { 0 };
                    sprintf(sql_cmd, "select * from books where book_id in (select book_id from userBook where user_id = %s)", user_id);

                    cout << sql_cmd << endl;
                    if (mysql_query(mysql_, sql_cmd) != 0) {
                        return_status(conn, "500");
                        return;
                    }

                    MYSQL_RES* res_set = NULL;
                    res_set = mysql_store_result(mysql_);
                    if (res_set == NULL) {
                        cout << "res_set is NULL" << endl;
                        return_status(conn, "404");
                        return;
                    }

                    unsigned long line = 0;
                    line = mysql_num_rows(res_set);

                    MYSQL_ROW row;

                    cJSON* root = cJSON_CreateObject();
                    cJSON* array = cJSON_CreateArray();

                    while ((row = mysql_fetch_row(res_set)) != NULL) {
                        cJSON* item = cJSON_CreateObject();

                        int column_index = 0;
                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "book_id", row[column_index]);
                        }
                        column_index++;

                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "book_name", row[column_index]);
                        }

                        column_index++;

                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "author", row[column_index]);
                        }

                        column_index++;

                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "Url", row[column_index]);
                        }

                        column_index++;

                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "content", row[column_index]);
                        }

                        cJSON_AddItemToArray(array, item);
                    }

                    cJSON_AddStringToObject(root, "code", "200");
                    cJSON_AddNumberToObject(root, "count", line);
                    cJSON_AddItemToObject(root, "books", array);

                    char* ret = cJSON_Print(root);
                    string strRet(ret);
                    string res = create_http_response(strRet);
                    conn->send(res);
                    conn->shutdown();
                    mysql_free_result(res_set);
                }
                else {
                    return_status(conn, "404");
                }

                mysql_close(mysql_);

            }
            else if (Url == "/myInfo") {
                MYSQL* mysql_ = msql_conn(dbUser, dbPwd, db);
                if (mysql_ == NULL)
                {
                    cout << "mysql is nullptr" << endl;
                    return;
                }
                //设置数据库编码，主要处理中文编码问题
                mysql_query(mysql_, "set names utf8");

                char sql_cmd[128] = { 0 };
                char user_id[16] = { 0 };
                if (getUserID(json, user_id) == 0) {
                    sprintf(sql_cmd, "select* from user where user_id = %s", user_id);

                    cout << sql_cmd << endl;
                    if (mysql_query(mysql_, sql_cmd) != 0) {
                        return_status(conn, "500");
                        return;
                    }

                    MYSQL_RES* res_set = NULL;
                    res_set = mysql_store_result(mysql_);
                    if (res_set == NULL) {
                        cout << "res_set is NULL" << endl;
                        return_status(conn, "404");
                        return;
                    }

                    unsigned long line = 0;
                    line = mysql_num_rows(res_set);

                    MYSQL_ROW row;

                    cJSON* root = cJSON_CreateObject();
                    cJSON* array = cJSON_CreateArray();

                    while ((row = mysql_fetch_row(res_set)) != NULL) {
                        cJSON* item = cJSON_CreateObject();

                        int column_index = 0;
                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "user_id", row[column_index]);
                        }
                        column_index++;

                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "userAccount", row[column_index]);
                        }

                        column_index++;
                        column_index++;
                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "create_time", row[column_index]);
                        }

                        cJSON_AddItemToArray(array, item);
                    }

                    cJSON_AddStringToObject(root, "code", "200");
                    cJSON_AddNumberToObject(root, "count", line);
                    cJSON_AddItemToObject(root, "userinfo", array);

                    char* ret = cJSON_Print(root);
                    string strRet(ret);
                    string res = create_http_response(strRet);
                    conn->send(res);
                    conn->shutdown();
                    mysql_free_result(res_set);
                }

                mysql_close(mysql_);

            }
            else if (Url == "/searchBook") {
                MYSQL* mysql_ = msql_conn(dbUser, dbPwd, db);
                if (mysql_ == NULL)
                {
                    cout << "mysql is nullptr" << endl;
                    return;
                }
                //设置数据库编码，主要处理中文编码问题
                mysql_query(mysql_, "set names utf8");

                char key[64] = { 0 };
                if (getSerachKey(json, key) == 0) {
                    char sql_cmd[256];
                    sprintf(sql_cmd, "SELECT * FROM books WHERE books.book_name LIKE '%%%s%%'", key);

                    cout << sql_cmd << endl;
                    if (mysql_query(mysql_, sql_cmd) != 0) {
                        return_status(conn, "500");
                        return;
                    }

                    MYSQL_RES* res_set = NULL;
                    res_set = mysql_store_result(mysql_);
                    if (res_set == NULL) {
                        cout << "res_set is NULL" << endl;
                        return_status(conn, "404");
                        return;
                    }

                    unsigned long line = 0;
                    line = mysql_num_rows(res_set);

                    MYSQL_ROW row;

                    cJSON* root = cJSON_CreateObject();
                    cJSON* array = cJSON_CreateArray();

                    while ((row = mysql_fetch_row(res_set)) != NULL) {
                        cJSON* item = cJSON_CreateObject();

                        int column_index = 0;
                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "book_id", row[column_index]);
                        }
                        column_index++;

                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "book_name", row[column_index]);
                        }

                        column_index++;

                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "author", row[column_index]);
                        }

                        column_index++;

                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "Url", row[column_index]);
                        }

                        column_index++;

                        if (row[column_index] != NULL) {
                            cJSON_AddStringToObject(item, "content", row[column_index]);
                        }

                        cJSON_AddItemToArray(array, item);
                    }

                    cJSON_AddStringToObject(root, "code", "200");
                    cJSON_AddNumberToObject(root, "count", line);
                    cJSON_AddItemToObject(root, "books", array);

                    char* ret = cJSON_Print(root);
                    string strRet(ret);
                    string res = create_http_response(strRet);
                    conn->send(res);
                    conn->shutdown();
                    mysql_free_result(res_set);
                }
                else {
                    return_status(conn, "404");
                    return;
                }

                mysql_close(mysql_);
            }
            else if (Url == "/addBookToUser") {
                MYSQL* mysql_ = msql_conn(dbUser, dbPwd, db);
                if (mysql_ == NULL)
                {
                    cout << "mysql is nullptr" << endl;
                    return;
                }
                //设置数据库编码，主要处理中文编码问题
                mysql_query(mysql_, "set names utf8");

                char user_id[16] = { 0 };
                char book_id[16] = { 0 };
                if (getUserID(json, user_id) == 0) {
                    if (getBookID(json, book_id) == 0) {
                        char sql_cmd[128] = { 0 };
                        sprintf(sql_cmd, "insert into userBook values(%s,%s,now())", book_id, user_id);
                        cout << sql_cmd << endl;
                        if (mysql_query(mysql_, sql_cmd) != 0) {
                            return_status(conn, "500");
                        }
                        else {
                            return_status(conn, "200");
                        }
                    }
                    else {
                        return_status(conn, "404");
                        return;
                    }
                }
                else {
                    return_status(conn, "404");
                    return;
                }
                mysql_close(mysql_);
            }
            else if (Url == "/delBookFromUser") {
                MYSQL* mysql_ = msql_conn(dbUser, dbPwd, db);
                if (mysql_ == NULL)
                {
                    cout << "mysql is nullptr" << endl;
                    return;
                }
                //设置数据库编码，主要处理中文编码问题
                mysql_query(mysql_, "set names utf8");

                char user_id[16] = { 0 };
                char book_id[16] = { 0 };
                if (getUserID(json, user_id) == 0) {
                    if (getBookID(json, book_id) == 0) {
                        char sql_cmd[128] = { 0 };
                        sprintf(sql_cmd, "delete from userBook where book_id = %s AND user_id = %s", book_id, user_id);

                        if ((mysql_exec(mysql_, sql_cmd) == -1)) {
                            return_status(conn, "500");
                            return;
                        }

                        return_status(conn, "200");
                    }
                    else {
                        return_status(conn, "404");
                        return;
                    }
                }
                else {
                    return_status(conn, "404");
                    return;
                }
                mysql_close(mysql_);
            }
            else if (Url == "/historyBooks") {
                MYSQL* mysql_ = msql_conn(dbUser, dbPwd, db);
                if (mysql_ == NULL)
                {
                    cout << "mysql is nullptr" << endl;
                    return;
                }
                //设置数据库编码，主要处理中文编码问题
                mysql_query(mysql_, "set names utf8");

                //点击历史时，获取信息
                vector<string> user_id_vec;

                char user_id[16] = { 0 };
                if (getUserID(json, user_id) == 0) {
                    char sql_cmd[128] = { 0 };
                    sprintf(sql_cmd, "SELECT book_id FROM historyBook WHERE user_id = %s ORDER BY use_time DESC", user_id);

                    cout << sql_cmd << endl;
                    if (mysql_query(mysql_, sql_cmd) != 0) {
                        return_status(conn, "500");
                        return;
                    }

                    MYSQL_RES* res_set = NULL;
                    res_set = mysql_store_result(mysql_);
                    if (res_set == NULL) {
                        cout << "res_set is NULL" << endl;
                        return_status(conn, "404");
                        return;
                    }

                    unsigned long line = 0;
                    line = mysql_num_rows(res_set);

                    MYSQL_ROW row;
                    while ((row = mysql_fetch_row(res_set)) != NULL) {
                        user_id_vec.push_back(row[0]);
                    }

                    cJSON* root = cJSON_CreateObject();
                    cJSON* array = cJSON_CreateArray();

                    MYSQL_RES* data_set = NULL;
                    for (int i = 0; i < user_id_vec.size(); i++) {
                        char cmd[128] = { 0 };
                        sprintf(cmd, "select * from books where book_id = %d", stoi(user_id_vec[i]));
                        cout << cmd << endl;
                        if (mysql_query(mysql_, cmd) != 0) {
                            return_status(conn, "500");
                            return;
                        }

                        data_set = mysql_store_result(mysql_);
                        if (data_set == NULL) {
                            cout << "data_set is NULL" << endl;
                            return_status(conn, "404");
                            return;
                        }

                        cJSON* item = cJSON_CreateObject();
                        MYSQL_ROW data_row;
                        if ((data_row = mysql_fetch_row(data_set)) != NULL) {

                            int column_index = 0;
                            if (data_row[column_index] != NULL) {
                                cJSON_AddStringToObject(item, "book_id", data_row[column_index]);
                            }
                            column_index++;

                            if (data_row[column_index] != NULL) {
                                cJSON_AddStringToObject(item, "book_name", data_row[column_index]);
                            }

                            column_index++;

                            if (data_row[column_index] != NULL) {
                                cJSON_AddStringToObject(item, "author", data_row[column_index]);
                            }

                            column_index++;

                            if (data_row[column_index] != NULL) {
                                cJSON_AddStringToObject(item, "Url", data_row[column_index]);
                            }

                            column_index++;

                            if (data_row[column_index] != NULL) {
                                cJSON_AddStringToObject(item, "content", data_row[column_index]);
                            }
                        }
                        cJSON_AddItemToArray(array, item);
                        mysql_free_result(data_set);
                    }

                    cJSON_AddStringToObject(root, "code", "200");
                    cJSON_AddNumberToObject(root, "count", line);
                    cJSON_AddItemToObject(root, "books", array);

                    char* ret = cJSON_Print(root);
                    string strRet(ret);
                    string res = create_http_response(strRet);
                    conn->send(res);
                    conn->shutdown();
                    mysql_free_result(res_set);
                }
                else {
                    return_status(conn, "404");
                }
                mysql_close(mysql_);
            }
            else if (Url.substr(0, 7) == "/images") {
                std::string imagePath = "." + Url;
                cout << imagePath << endl;

                std::ifstream imageFile(imagePath, std::ios::binary);

                if (!imageFile.is_open()) {
                    return_status(conn, "404");
                    return;
                }

                std::stringstream buffer;
                buffer << imageFile.rdbuf();
                std::string imageData = buffer.str();

                int imageLength = imageData.length();

                std::string response = "HTTP/1.1 200 OK\r\n";
                response += "Content-Type: image/jpg\r\n";
                response += "Content-Length: " + std::to_string(imageLength) + "\r\n";
                response += "Connection: keep-alive\r\n";
                response += "\r\n";
                response += imageData;
                conn->send(response);
                conn->shutdown();

                imageFile.close();
            }
            else if (Url.substr(0, 8) == "/content") {
                std::string NovelPath = "." + Url;
                cout << NovelPath << endl;

                int offset = 0;

                // if (getOffset(json, offset) != 0) {
                //     cout << "offset is failed." << endl;
                //     return_status(conn, "500");
                //     return;
                // }

                std::ifstream file(NovelPath);
                if (!file.is_open()) {
                    cout << "file is open filed" << endl;
                    return_status(conn, "999");
                    return;
                }

                file.seekg(offset * 100000);

                std::stringstream buffer;
                char content[100001];
                int numRead = 0;

                // 读取5000个字符的内容
                while ((numRead < 100000) && file.get(content[numRead])) {
                    numRead++;
                }

                content[numRead] = '\0'; // 添加字符串结束符
                buffer << content;

                std::string body = buffer.str();

                std::string response = "HTTP/1.1 200 OK\r\n";
                response += "Content-Type: text/plain;charset=UTF-8\r\n";
                response += "Content-Length: " + std::to_string(body.length()) + "\r\n";
                response += "Connection: keep-alive\r\n";
                response += "\r\n";
                response += body;

                conn->send(response);
                conn->shutdown();
                file.close();
            }
            else {
                return_status(conn, "404");
            }
        }
    }


    std::string create_http_response(const std::string& json_body) {
        std::string response = "HTTP/1.1 200 OK\r\n";
        response += "Server: " + serverName + "\r\n";
        response += "Content-Type: application/json\r\n";
        response += "Content-Length: " + std::to_string(json_body.length()) + "\r\n";
        response += "Connection: keep-alive\r\n";
        response += "\r\n";
        response += json_body;
        return response;
    }

    std::string getRequestMethod(const std::string& request) {
        int idx = request.find(' ');
        if (idx == std::string::npos) {
            cout << "std::string::npos" << endl;
            return "";
        }
        std::string method = request.substr(0, idx);
        if (method == "POST" || method == "GET") {
            return method;
        }

        return "";
    }

    std::string getRequestURL(const std::string& request) {
        int start_idx = request.find(' ');
        if (start_idx == std::string::npos) {
            cout << "std::string::npos" << endl;
            return "";
        }

        int end_idx = request.find(' ', start_idx + 1);

        int n = end_idx - start_idx - 1;

        string Url = request.substr(start_idx + 1, n);

        return Url;
    }

    std::string getRequestJson(const std::string& request) {
        int start_idx = request.find("\r\n\r\n");

        if (start_idx == std::string::npos) {
            cout << "std::string::npos" << endl;
            return "";
        }

        std::string jsonStr = request.substr(start_idx + 4);

        return jsonStr;
    }

    int getUserInfo(std::string json, char* userName, char* pwd) {

        cJSON* root = cJSON_Parse(json.c_str());

        if (root == NULL) {
            cout << "root is NULL" << endl;
            return -1;
        }


        cJSON* child1 = cJSON_GetObjectItem(root, "user");
        if (child1 == NULL) {
            cout << "child1 is nullptr" << endl;
            return -1;
        }
        cJSON* child2 = cJSON_GetObjectItem(root, "pwd");

        if (child2 == NULL) {
            cout << "child2 is nullptr" << endl;
            return -1;
        }

        strcpy(userName, child1->valuestring);
        strcpy(pwd, child2->valuestring);

        //输出
        cout << userName << endl;
        cout << pwd << endl;

        cJSON_Delete(root);

        return 0;
    }

    int getUserInfo(std::string json, char* userName, char* pwd, char* newPwd) {

        cJSON* root = cJSON_Parse(json.c_str());

        if (root == NULL) {
            cout << "root is NULL" << endl;
            return -1;
        }


        cJSON* child1 = cJSON_GetObjectItem(root, "user");
        if (child1 == NULL) {
            cout << "child1 is nullptr" << endl;
            return -1;
        }
        cJSON* child2 = cJSON_GetObjectItem(root, "pwd");

        if (child2 == NULL) {
            cout << "child2 is nullptr" << endl;
            return -1;
        }

        cJSON* child3 = cJSON_GetObjectItem(root, "newPwd");
        if (child3 == NULL) {
            cout << "child3 is NULL" << endl;
            return -1;
        }

        strcpy(userName, child1->valuestring);
        strcpy(pwd, child2->valuestring);
        strcpy(newPwd, child3->valuestring);

        //输出
        cout << userName << endl;
        cout << pwd << endl;
        cout << newPwd << endl;
        cJSON_Delete(root);

        return 0;
    }

    int checkUserInfo(char* userName, char* pwd, char* token) {

        MYSQL* mysql_ = msql_conn(dbUser, dbPwd, db);
        if (mysql_ == NULL)
        {
            cout << "mysql is nullptr" << endl;
            return -1;
        }
        //设置数据库编码，主要处理中文编码问题
        mysql_query(mysql_, "set names utf8");

        char sql_cmd[128] = { 0 };

        sprintf(sql_cmd, "SELECT user_id FROM user WHERE userAccount = '%s' AND userPwd = '%s'", userName, pwd);
        cout << sql_cmd << endl;
        if (process_result_one(mysql_, sql_cmd, token) == 0) {
            return 0;
        }

        mysql_close(mysql_);
        return -1;
    }

    int getOffset(std::string json, int& offset) {
        cJSON* root = cJSON_Parse(json.c_str());

        if (root == NULL) {
            cout << "root is NULL" << endl;
            return -1;
        }


        cJSON* child1 = cJSON_GetObjectItem(root, "offset");
        if (child1 == NULL) {
            cout << "child1 is nullptr" << endl;
            return -1;
        }

        char index[128] = { 0 };

        strcpy(index, child1->valuestring);

        offset = atoi(index);

        return 0;
    }


private:
    void initMysql() {
        strcpy(dbUser, "root");
        strcpy(dbPwd, "Qq530863157.");
        strcpy(db, "novelDB");
    }

    void return_status(const TcpConnectionPtr& conn, const char* code) {
        cJSON* object = cJSON_CreateObject();
        cJSON_AddStringToObject(object, "code", code);
        char* ret = cJSON_Print(object);
        string strRet(ret);
        string res = create_http_response(strRet);
        conn->send(res);

        cJSON_Delete(object);
        conn->shutdown();
    }

    int getBookID(std::string json, char* book_id) {
        cJSON* root = cJSON_Parse(json.c_str());

        if (root == NULL) {
            cout << "root is NULL" << endl;
            return -1;
        }

        cJSON* child1 = cJSON_GetObjectItem(root, "book_id");

        if (child1 == NULL) {
            cout << "book_id is NULL" << endl;
            return -1;
        }

        strcpy(book_id, child1->valuestring);

        cJSON_Delete(root);
        return 0;
    }

    int getUserID(std::string json, char* user_id) {
        cJSON* root = cJSON_Parse(json.c_str());

        if (root == NULL) {
            cout << "root is NULL" << endl;
            return -1;
        }

        cJSON* child1 = cJSON_GetObjectItem(root, "user_id");

        if (child1 == NULL) {
            cout << "user_id is NULL" << endl;
            return -1;
        }

        strcpy(user_id, child1->valuestring);

        cJSON_Delete(root);
        return 0;
    }

    int getSerachKey(std::string json, char* key) {
        cJSON* root = cJSON_Parse(json.c_str());
        if (root == NULL) {
            cout << "root is NULL" << endl;
            return -1;
        }

        cJSON* child1 = cJSON_GetObjectItem(root, "key");

        if (child1 == NULL) {
            cout << "key is NULL" << endl;
            return -1;
        }

        strcpy(key, child1->valuestring);

        cJSON_Delete(root);
        return 0;
    }

private:
    TcpServer server;
    EventLoop* loop;
    string serverName;
    MYSQL* mysql_;
};

int main(void) {
    EventLoop loop;
    InetAddress addr(80, "172.19.7.133");

    Server server(&loop, addr, "Harmony");

    server.start();

    return 0;
}